
module iTimer.util.Time ;

import iTimer.Types;

private import tango.time.Time;
private import tango.time.Clock;
private import tango.time.WallClock;

alias double ev_time_t ;

struct vTime {
    private {
        // Time            _time ;
        // Date            _date ;
        // TimeOfDay    _timeofday ;
    }
    int date ;
    int dow ;
    int time ;
    // long    ts ;
    
    static vTime now() {
        vTime   _this ;
        Time    _now    = WallClock.now;
        tango.time.Time.DateTime    _date = Clock.toDate(_now);
        // _this._time = WallClock.now;
        // _this._date      = _date.date ;
        // _this._timeofday  = _date.time ;
        
        // _this.ts    = _now.unix.seconds ;
        
        _this.date  =  _date.date.year * 10000 + _date.date.month  * 100 + _date.date.day ;
        _this.dow   = _date.date.dow - 1 ;
        if( _this.dow  < 0 ) {
            _this.dow   = 6 ;
        }
        _this.time  = _date.time.hours * 10000 +  _date.time.minutes * 100 + _date.time.seconds  ;
        
        return _this ;
    }
    
    static double ev_time_now (){
        FILETIME ft;
        ULARGE_INTEGER ui;
        GetSystemTimeAsFileTime (&ft);
        ui.LowPart  = ft.dwLowDateTime;
        ui.HighPart = ft.dwHighDateTime;
        return (ui.QuadPart - 116444736000000000) * 1e-7;
    }
    
    
    static DWORD uptime (){
        DWORD _time = GetTickCount();
        return _time ;
    }
    
    static void Init(){
        has_adjust_clock;
        auto it = now ;
        is_day_changed(&it);
    }
    
    static bool is_day_changed(vTime* it) in {
        assert(it !is null);
    } body {
        static int _last_date_number    = 0 ;
        if( it.date != _last_date_number ) {
            _last_date_number   = it.date ;
            return true ;
        }
        return false ;
    }
    
    static bool has_adjust_clock() {
        static DWORD _last_update_time = 0 ;
        static double _last_now_uptime = 0 ;
        
        auto _update_time   = uptime();
        scope(exit) {
            _last_update_time   = _update_time ;
            _last_now_uptime    = _now_time - ( _update_time / 1000f ) ;
        }
        
        auto _now_time   = ev_time_now() ;
        
        if( _last_now_uptime < 1 ) {
            // version(DEV) log!(__FILE__,__LINE__)("has_adjust_clock init" );
            return false ;
        }
        
        auto _passed_now_time = cast(DWORD) (_now_time - _last_now_uptime) * 1000 ;
        auto _passed_diff   = _update_time - _passed_now_time ;
        if( _passed_diff < 0 ) {
            _passed_diff    = 0 - _passed_diff ;
        }
    
        if( _passed_diff <= 2000 ) {
            return false ;
        }
        
        // version(DEV) log!(__FILE__,__LINE__)("_passed_diff={}", _passed_diff  );
        
        return true ;
    }
}